
/// MLSDEFORMER source code
/// by Alvaro Cuno, LCG-COPPE-UFRJ 
/// bugs? email-me: alvaroecp@gmail.com
/// January, 2007

#ifndef __DEFORMATION_SKELMESH__
#define __DEFORMATION_SKELMESH__

#include "../typedefs.h"
#include "../core/constraints.h"
#include "../core/deformation.h"
#include "meshWithSkeleton.h"
#include "deformationMesh.h"

#include <cpplapack.h>

//~ namespace MLS {

///
///
///
class DeformationSkelMesh : public DeformationMesh {
   
   typedef CPPL::dgematrix    MatrixCPPL;   ///< A CPPLapack matrix
   typedef CPPL::dcovector    VectorCPPL;   ///< A CPPLapack column vector
   
public:
   DeformationSkelMesh();
   DeformationSkelMesh(MeshWithSkeleton *m);
   virtual ~DeformationSkelMesh();
   
   /// Sets the mesh to be deformed
   void setMesh(MeshWithSkeleton *m);
   
   /// Prepares the deformer to compute the deformation
   void setting(const Constraints *constraints);
   
   /// Executes the MLS-deformation induced by the deformed constraints
   ///@param constraints pointer to current constraints positions
   void execute_deformation(const Constraints *constraints);
   
   void rotate(const Point3 &o, const Vector3 &u, Number angle);
   
private:
   void compute_WeightsTable(const Constraints *constraints);
   void initialize();
   void initialize_pstarlist_model();
   
   /// Computes the rotation using quaternios
   void computeQuatRotation(const Number v[], const Number &qs, const Vector3 &qv);
   
   inline Number weight2(unsigned ivertice, unsigned ictrlpoint) {
      return VB_WeightsTable[ictrlpoint*texSizetexSize + ivertice];
   }
   
   inline Number distance(unsigned ivertice, unsigned ictrlpoint) {
      return DistancesTable[ictrlpoint*texSizetexSize + ivertice];
   }
   
private:
   
   void compRotTra_simple(unsigned int i);
   void project_deformation_on_mesh_using_simple();
   
   /// Returns the rotation applied to bone i
   void getRotationRep(unsigned int i);
   
   /// Returns the rotation given by projecting bones on the perpendicular plane 
   /// defined by bone i
   Vector3 getRotationAroundBoneRep(unsigned int i);
   
   /// Returns the translation applied to bone i in function of vertex v
   Vector3 getTranslationRep(unsigned i, Vertex_handle v);
   
   void project_deformation_dualquat_interquat();
   
   void project_deformation_using_quaternions();
   
   void project_deformation_on_mesh_linear();
   
   void project_deformation_using_u();
   
   void project_deformation_on_mesh_std_dualquat();
   
   void noproject_deformation();
private:
   
   MeshWithSkeleton                  *model;
   
   Number                            *VB_WeightsTable; // vertices bones weights table for all bones using pi and qi dynamics 
   Number                            *DistancesTable; // 
   
   std::vector<Vector3>              vhatl_mesh;  //< list of model's vhat vectors : vhat = p - p*
   std::vector<Vector3>              ul;  //< list of u vectors
   std::vector<Point3>               pstarlistv;  //< list of u vectors
   
   std::vector<Vector3>              ubones; // rotation representation for bones
   std::vector<Vector3>              tbones; // translation representation for bones
   
   std::vector<Vector3>              tvectors0; // translation applied to joints of bones
   std::vector<Vector3>              tvectors1; // translation applied to joints of bones
   std::vector<Number>               tscalar0; // 
   std::vector<Number>               tscalar1; // 

   std::vector<Vector3>              tlvectors0; // translation applied to joints of bones
   std::vector<Vector3>              tlvectors1; // translation applied to joints of bones

   std::vector<std::vector<Number> > old_angle;
   std::vector<int>                  turns;
   
   Number anglebone5;
   Number normau6, normau10;
   
   bool comprotaround;
   int                              numframe;
   Vector3                          vetor[2];
};

//~ } // end MLS namespace

#endif
